package com.flag.liutao.modules.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flag.liutao.common.enums.UserStatusEnum;
import com.flag.liutao.common.handler.MyException;
import com.flag.liutao.modules.role.domain.Role;
import com.flag.liutao.modules.role.domain.UserRole;
import com.flag.liutao.modules.role.service.IRoleService;
import com.flag.liutao.modules.role.service.IUserRoleService;
import com.flag.liutao.modules.student.domain.Classes;
import com.flag.liutao.modules.student.service.IClassesService;
import com.flag.liutao.modules.user.domain.User;
import com.flag.liutao.modules.user.mapper.UserMapper;
import com.flag.liutao.modules.user.param.UserCountQueryParam;
import com.flag.liutao.modules.user.param.UserParam;
import com.flag.liutao.modules.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flag.liutao.modules.user.vo.UserCountVo;
import com.flag.liutao.modules.user.vo.UserQueryVo;
import com.flag.liutao.modules.user.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author godM
 * @since 2022-11-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {


    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IClassesService classesService;
    @Autowired
    private IRoleService roleService;

    /**
     * 通过ID 获取用户权限
     * @param id
     * @return
     */
    @Override
    public List<String> getAuthorities(Long id) {
        return userMapper.getAuthorities(id);
    }

    /**
     * 通过id 获取用户信息
     * @param uid
     * @return
     */
    @Override
    public UserVo getUserInfoById(String uid) {
        UserVo result = new UserVo();
        BeanUtil.copyProperties(userMapper.selectById(uid),result);
        return result;
    }

    /**
     * 获取全部用户信息
     * @param page
     * @param limit
     * @param keyword
     * @param gradeId
     * @param majorId
     * @param deptId
     * @param unitId
     * @param roleId
     * @param status
     * @return
     */
    @Override
    public Map<String, Object> getUserPage(int page, int limit, String keyword, Long gradeId, Long majorId, Long deptId, Long unitId, Long roleId, Integer status) {
        IPage<UserQueryVo> iPage = new Page<>(page,limit);
        IPage<UserQueryVo> pageDB = userMapper.getUserPage(iPage,keyword,gradeId,majorId,deptId,unitId,roleId,status);
        Map<String,Object> map = new HashMap<>();
        map.put("content",pageDB.getRecords());
        map.put("total",pageDB.getTotal());
        return map;
    }

    /**
     * 添加用户信息
     * @param param
     */
    @Override
    public void addUser(UserParam param) {
        LambdaQueryWrapper<User> lqwPhone  = new LambdaQueryWrapper<>();
        lqwPhone.eq(User::getPhone,param.getPhone()).or().eq(User::getUserName,param.getUserName());
        User userPhone = userMapper.selectOne(lqwPhone);
        if(ObjectUtil.isNotNull(userPhone)){
            throw new MyException("手机号码："+param.getPhone()+"已被使用");
        }
        LambdaQueryWrapper<User> lqwUnique  = new LambdaQueryWrapper<>();
        lqwUnique.eq(User::getUnique,param.getUnique());
        User userUnique = userMapper.selectOne(lqwPhone);
        if(ObjectUtil.isNotNull(userUnique)){
            throw new MyException("学号："+param.getUnique()+"已被使用");
        }
        User user = new User();
        BeanUtil.copyProperties(param,user);
        user.setPreparationTime(new Date());
        user.setStatus(UserStatusEnum.STATUS_0.getValue());
        user.setUserName(param.getPhone());
        user.setPassword(passwordEncoder.encode("123456"));
        userMapper.insert(user);
        //获取年级ID
        Classes classes = classesService.getById(param.getClassId());
        Long gradeId = classes.getGradeId();
        //获取用户ID
        LambdaQueryWrapper<User> lqwUserName = new LambdaQueryWrapper<>();
        lqwUserName.eq(User::getUserName,param.getPhone());
        User userDB = userMapper.selectOne(lqwUserName);
        Long userId = userDB.getId();

        //获取预备队员ID
        LambdaQueryWrapper<Role> lqwRole = new LambdaQueryWrapper<>();
        lqwRole.eq(Role::getRoleKey,"sys_role:preparation_member");
        Role role = roleService.getOne(lqwRole);
        Long roleId = role.getId();
        //添加后默认为预备队员
        UserRole userRole = new UserRole();
        userRole.setGradeId(gradeId);
        userRole.setRoleId(roleId);
        userRole.setUserId(userId);
        userRole.setUnitId(param.getUnitId());
        userRoleService.save(userRole);
    }

    /**
     * 编辑用户
     * @param param
     */
    @Override
    public void editUser(UserParam param) {
        User user = userMapper.selectById(param.getId());
        if(ObjectUtil.isNull(user)){
            throw new MyException("该用户不存在");
        }

        LambdaQueryWrapper<User> lqwPhone  = new LambdaQueryWrapper<>();
        lqwPhone.eq(User::getPhone,param.getPhone()).or().eq(User::getUserName,param.getUserName());
        User userPhone = userMapper.selectOne(lqwPhone);
        if(ObjectUtil.isNotNull(userPhone) && param.getId()!=user.getId()){
            throw new MyException("手机号码："+param.getPhone()+"已被使用");
        }

        LambdaQueryWrapper<User> lqwUnique  = new LambdaQueryWrapper<>();
        lqwUnique.eq(User::getUnique,param.getUnique());
        User userUnique = userMapper.selectOne(lqwPhone);
        if(ObjectUtil.isNotNull(userUnique) && param.getId()!=user.getId()){
            throw new MyException("学号："+param.getUnique()+"已被使用");
        }
        User userDB = new User();
        BeanUtil.copyProperties(param,userDB);
        if (StrUtil.isNotEmpty(param.getPhone())) {
            userDB.setUserName(param.getPhone());
        }
        userMapper.updateById(userDB);
    }

    /**
     * 删除用户
     * @param id
     */
    @Override
    public void delUser(Long id) {
        userMapper.deleteById(id);
        LambdaQueryWrapper<UserRole> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserRole::getUserId,id);
        UserRole userRole = userRoleService.getOne(lqw);
        if(ObjectUtil.isNotNull(userRole)){
            userRoleService.removeById(userRole.getId());
        }
    }


    /**
     * 通过ID 获取用户详细信息
     * @param id
     * @return
     */
    @Override
    public UserQueryVo getUserQueryInfoById(Long id) {
        return userMapper.selectUserInfoById(id);
    }

    /**
     * 编辑队员状态
     * @param status
     * @param id
     */
    @Override
    public void editUseStatus(Integer status,Long id) {
        User user = userMapper.selectById(id);
        if(ObjectUtil.isNull(user)){
            throw new MyException("该用户不存在");
        }
        UpdateWrapper<User> uw = new UpdateWrapper<>();
        uw.eq("id",id);
        switch (status){
            case 0:
                uw.set("status",UserStatusEnum.STATUS_0.getValue());
                uw.set("preparation_time",new Date());
                uw.set("join_time",null);
                uw.set("leave_Time",null);uw.set("retire_Time",null);
                break;
            case 1:
                uw.set("status",UserStatusEnum.STATUS_1.getValue());
                uw.set("join_time",new Date());
                uw.set("leave_Time",null);uw.set("retire_Time",null);
                break;
            case -1:
                uw.set("status",UserStatusEnum.STATUS_LEAVE.getValue());
                uw.set("leave_Time",new Date());
                uw.set("retire_Time",null);
                break;
            case -2:
                uw.set("status",UserStatusEnum.STATUS_RETIRE.getValue());
                uw.set("leave_Time",null);uw.set("retire_Time",new Date());
                break;
        }
        this.update(uw);
    }

    /**
     * 获取队员数目
     * @param param
     * @return
     */
    @Override
    public Map<String, Object> getUserCountByUnit(UserCountQueryParam param) {
        List<UserCountVo> list = userMapper.selectUserCount(param.getGradeId(),param.getSex());
        Map<String,Object> map = new HashMap<>();
        List<String> xAxis = new ArrayList<>();
        List<Integer> xData = new ArrayList<>();
        for (UserCountVo userCountVo : list) {
            xAxis.add(userCountVo.getName());
            xData.add(userCountVo.getValue());
        }
        map.put("xAxis",xAxis);
        map.put("xData",xData);
        map.put("result",list);
        return map;
    }
}
